package com.eian.boot.module.system.auth.service;

import cn.dev33.satoken.stp.StpUtil;
import com.eian.boot.common.core.enums.CommonEnum;
import com.eian.boot.common.enums.PermissionTypeEnum;
import com.eian.boot.module.system.permission.service.PermissionCacheService;
import com.eian.boot.module.system.permission.service.SysPermissionService;
import com.eian.boot.module.system.role.model.entity.SysRoleEntity;
import com.eian.boot.module.system.role.service.SysRoleService;
import com.eian.boot.security.core.service.AbstractSaPermission;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;

import static com.eian.boot.table.Tables.*;

/**
 * SaToken权限验证实现
 *
 * @author alex.meng
 */
@Service
@AllArgsConstructor
public class SaPermissionImpl extends AbstractSaPermission {
    private final SysRoleService roleService;
    private final SysPermissionService permissionService;
    private final PermissionCacheService cacheService;

    @Override
    protected List<String> getPermissions() {
        if (!StpUtil.isLogin()) {
            return Collections.emptyList();
        }
        Long userId = StpUtil.getLoginIdAsLong();

        List<String> cached = cacheService.getUserPermissions(userId);
        if (cached != null && !cached.isEmpty()) {
            return cached;
        }

        List<String> perms = permissionService.queryChain()
                .select(sys_permission.code)
                .from(sys_permission)
                .innerJoin(sys_role_permission).on(sys_role_permission.permission_id.eq(sys_permission.id))
                .innerJoin(sys_role).on(sys_role_permission.role_id.eq(sys_role.id))
                .innerJoin(sys_user_role).on(sys_user_role.role_id.eq(sys_role.id))
                .where(sys_user_role.user_id.eq(userId)
                        .and(sys_permission.type.eq(PermissionTypeEnum.BUTTON.getValue()))
                        .and(sys_role.status.eq(CommonEnum.ENABLED.getValue())))
                .listAs(String.class);

        if (!perms.isEmpty()) {
            cacheService.setUserPermissions(userId, perms);
        }

        return perms;
    }

    @Override
    protected List<String> getRoles() {
        if (!StpUtil.isLogin()) {
            return Collections.emptyList();
        }
        Long userId = StpUtil.getLoginIdAsLong();

        List<String> cached = cacheService.getUserRoles(userId);
        if (cached != null && !cached.isEmpty()) {
            return cached;
        }

        List<SysRoleEntity> roles = roleService.getUserRoles(userId);
        List<String> roleCodes = roles.stream().map(SysRoleEntity::getCode).toList();

        if (!roleCodes.isEmpty()) {
            cacheService.setUserRoles(userId, roleCodes);
        }

        return roleCodes;
    }
}

